﻿package code {
	
	import flash.display.Sprite;
	import flash.events.*;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import com.as3toolkit.events.KeyboarderEvent;
	import com.as3toolkit.ui.Keyboarder;
	import code.Characters.*;
	import GUI.Title;
	import GUI.Select;
	
	public class Field extends Sprite {
		public var player1, player2:Player;
		var playerList:Array;
		
		var turn:int;
		
		var keyboardStuff:Keyboarder;
		
		var gameState:Array;  // acts as an enum
		var currentState:String;
		var currentScreen:Sprite;
		var title:Title;
		var select:Select;
		// XML stuff
		var xml:XML = new XML();
		var xmlLoader:URLLoader = new URLLoader(); // XML Loader 
		var xmlLoader1:URLLoader = new URLLoader(); // XML Loader 
		var accModifier:Number;
		
		var animationDone, gameOver, attackAgain:Boolean;
		var drawCounter:int;
		var gb:GameBackground = new GameBackground();
		
		public var channel2:SoundChannel = new SoundChannel();
		public var externalSound:Sound;
		
		public function Field() {
			currentState = Const.TITLE_MENU;
			
			xmlLoader.addEventListener(Event.COMPLETE, loadXML);
			xmlLoader.load(new URLRequest("videoGameNerd.xml"));
			xmlLoader1.addEventListener(Event.COMPLETE, loadXML);
			xmlLoader1.load(new URLRequest("comicBookNerd.xml"));

			keyboardStuff = new Keyboarder(this);
			
			////title = new Title();
			gameState = new Array("TitleMenu", "Instructions", "Setup", "Credits", "Game", "Pause", "End");


			
			playerList = new Array();

			animationDone = true;
			
			turn = 1;
			//init();
		}
		
		public function init(){
			title = new Title();
			addChild(title);
		}
		
		// starts sound 
		private function playMusic(i:int):void
		{
			
			var req:URLRequest;
			if(i == 0)
			req = new URLRequest("Ultimate Nerd Music/Preferable final/Battle Song.mp3");		
			else
			req = new URLRequest("Ultimate Nerd Music/Preferable final/Battle Song Repeat.mp3");		
    		externalSound = new Sound(req);
    		channel2 = externalSound.play();
    		channel2.addEventListener(Event.SOUND_COMPLETE, loopMusic);
		}
		
		// when background sound is done loop it
		private function loopMusic(e:Event):void
		{
    		if (channel2 != null)
    		{
        		channel2.removeEventListener(Event.SOUND_COMPLETE, loopMusic);
        		playMusic(1);
    		}
		}
		
		public function gameInit(){
			title.remove();
			removeChild(title);
			select = new Select(player1, player2);
			
			addChild(select);
			currentState = Const.SETUP;
		}
		
		public function gameInit2(){
			select.remove();
			removeChild(select);
			
			// sets up initial player location values
			player1.x = 200;
			player1.y = 220;
			
			player2.x = 1000;
			player2.y = 200;
			
			player1.IsAttacking = true;  // sets up one player to attack first
						
			playerList.push(player1);
			playerList.push(player2);

			
			playMusic(0);
			addChild(gb);
			addChild(player1);
			addChild(player2);
			
			player1.Gui.name_txt.text = "P1";
			player1.Gui.hp_txt.text = player1.Hp;
			player1.Gui.np_txt.text = player1.Mana;
			
			player1.Gui.first_txt.text = "Q:Stored";
			player1.Gui.second_txt.text = "W:Basic";
			player1.Gui.third_txt.text = "E:Hand";
			player1.Gui.back_txt.text = "F:Back";
			
			
			addChild(player1.Gui);
			
			// Move Player 2
			player2.Gui.name_txt.text = "P2";
			
			player2.Gui.hp_txt.text = ""+player2.Hp;
			player2.Gui.np_txt.text = ""+player2.Mana;
			
			player2.Gui.first_txt.text = "U:Stored";
			player2.Gui.second_txt.text = "I:Basic";
			player2.Gui.third_txt.text = "O:Hand";
			player2.Gui.back_txt.text = ";:Back";
			player2.Gui.x += 640;
			
				
			
			addChild(player2.Gui);
			
			addEventListener(Event.ENTER_FRAME, update);
			addEventListener(Event.ENTER_FRAME, drawGame);
			Keyboarder.Instance.addEventListener(KeyboarderEvent.FIRST_PRESS, pressed);
		}
		
		public function loadXML(e:Event){
			xml = new XML(e.target.data);
			if(xml.@name == "videoGame"){
				player1 = new VideoGameNerd(xml, 1);  // fix later to make this so it works for both player
			}
			else if(xml.@name == "comicBook"){
				player2 = new ComicBookNerd(xml, 2);
				init();
			}


		}
		
		public function update(e:Event):void{
			if(animationDone)
				checkDamage();
			if(gameOver)
				destroy();
		}
		
		public function drawGame(e:Event):void{
			if(!animationDone)
				doGame();
		}
		
		public function doGame(){
			var attacker:Player;
			var defender:Player;
			if(!player1.DrawAttack){  // means that they will be defending next turn
				attacker = player1;
				defender = player2;
			}
			else{
				attacker = player2;
				defender = player1;
			}
			if(drawCounter == 0){
				if(attacker == player1)
					gb.gotoAndPlay("attackL");
				else if(attacker == player2)
					gb.gotoAndPlay("attackR");
				attacker.x = (stage.stageWidth / 2) - 100;
				attacker.y = (stage.stageHeight /2) - 100;
				defender.x = -200;
				defender.y = -200;
				attacker.gotoAndStop("attack");
			}
			else if(drawCounter == 100){
				gb.gotoAndStop("defense");
				defender.x = (stage.stageWidth / 2) - 100;
				defender.y = (stage.stageHeight /2) - 100;
				attacker.x = -200;
				attacker.y = -200;
				defender.gotoAndStop("defense");
			}
			else if(drawCounter == 200){
				animationDone = true;
				player1.gotoAndStop("normal");
				player1.x = 200;
				player1.y = 220;
				player2.x = 1000;
				player2.y = 200;
				player2.gotoAndStop("normal");
				gb.gotoAndPlay("normal");
			}
			drawCounter++;
		}
		
		/*
		// checks for damage done
		// order is:
		// do Modifiers
		// defending player item check
		// defending player defense check
		// attacking player item check
		// attacking player attack check
		// deals damage*/
		public function checkDamage():void{
			var p1, p2:Player;
			player1.AttackAgain = false;
			player2.AttackAgain = false;
			
			playerList[0] = player1;
			playerList[1] = player2;
			
			if(turn == 1){
				p1 = playerList[0];  // based on turn, switches "whos on first"
				p2 = playerList[1];
			}
			else{
				p1 = playerList[1];
				p2 = playerList[0];
			}
			
			if(p1.MoveComplete && p2.MoveComplete){
				var dmgToTake:Number = 0;
				var canBeHit:Boolean = true;
				accModifier = 0;
				p1.TempDefense = 0; // resets modifiers
				p2.TempDefense = 0;
				
				// checks to see if they have anything to modify
				checkModifiers(p1);
				checkModifiers(p2);
				
				if(checkIfHit(p2)){
					if(p2.CardUsing != null && p2.CardUsing.Type == "item"){
						checkItem(p2);
					}
					else if(p2.CardUsing != null && p2.CardUsing.Type == "defense"){  // checks for the defense modifier
						if(p2.CardUsing.Effect == "def"){	// if checks for defense effect
							p2.TempDefense += p2.CardUsing.Modifier;
						}
						else if(p2.CardUsing.Effect == "accS"){
							canBeHit = false;	// currently all accuracy self allows for avoidance of attacks
						}
						else if(p2.CardUsing.Effect == "accO"){
							accModifier = p2.CardUsing.Modifier;  // sets the modifier for checking if player1 can hit
						}
					}
				}
				if(checkIfHit(p1)){
					trace("reaches here " + p1.CardUsing.Type);
					if(p1.CardUsing.Type == "item"){
						checkItem(p1);
					}

					else if(p1.CardUsing.Type == "attack" || p1.CardUsing.Type == "attackN"){
						trace("Player Stats Before Calc: Card Using Modifiers: " + p1.CardUsing.Modifier + " P1 Attack: " + p1.Attack + " P1 Temp Attack: " + p1.TempAttack + " P2 Defense: " + p2.Defense + " P2 TempDefense: " + p2.TempDefense);
						dmgToTake = (p1.CardUsing.Modifier + p1.Attack + p1.TempAttack) - (p2.Defense + p2.TempDefense); // does the defense - damage
						if(dmgToTake <= 0){
							dmgToTake = 1; // damage is always at least 1
						}
						trace("Damage to Take After Calc: " + dmgToTake);
					}

				}

				
				if(canBeHit){
					trace(p2.PlayerName + " Before Hit: " + p2.Hp);
					trace("Damage to take: " + dmgToTake);
					p2.Hp -= dmgToTake;
					p1.Mana += (2/3) * dmgToTake;
					p2.Mana += (1/3) * dmgToTake;
					trace(p2.PlayerName + ": " + p2.Hp);
				}
				
				p1.MoveComplete = false;
				p2.MoveComplete = false;
				p1.switchPhase();
				p2.switchPhase();
				
				animationDone = false;
				drawCounter = 0;
				
				
				if(checkLose()){
					animationDone = true;
					gameOver = true;
				}
				
				if(p1.AttackAgain){
					p2.MoveComplete = true;
					p2.CardUsing = null;
				}
				else if(p2.AttackAgain){
					p1.MoveComplete = true;
					p1.CardUsing = null;
				}
				else
					if(turn == 1){
						turn++;
					}
					else if(turn == 2){
						turn--;
					}
					
					
				
				// Update stuff
				player1.Gui.hp_txt.text = ""+player1.Hp;
				player1.Gui.np_txt.text = ""+player1.Mana;
				
				player2.Gui.hp_txt.text = ""+player2.Hp;
				player2.Gui.np_txt.text = ""+player2.Mana;
			}
		}
		
		
		// checks the modifiers and adjusts the stats accordingly
		public function checkModifiers(p1:Player){
			trace("P1 Modifiers List Length: " + p1.Modifiers.length);
			for(var i:int = 0; i < p1.Modifiers.length; i++){
				if(p1.IsAttacking && p1.Modifiers[i].Stat == "attack"){ // checks to see if phase to buff, if it is, calls the modify method
					if(p1.Modifiers[i].modify(p1)){
						p1.Modifiers.splice(i, 1);
						i--;
					}
				}
				else if(!p1.IsAttacking && p1.Modifiers[i].Stat == "defense"){  // if defense phase, modify defense
					if(p1.Modifiers[i].modify(p1)){
						p1.Modifiers.splice(i, 1);
						i--;
					}
				}
				else if(p1.Modifiers[i].Stat == "hp"){
					if(p1.Modifiers[i].modify(p1)){
						p1.Modifiers.splice(i, 1);
						i--;
					}
				}
				else if(p1.Modifiers[i].Stat == "pwr"){
					if(p1.Modifiers[i].modify(p1)){
						p1.PoweredUp = false;
						p1.Modifiers.splice(i, 1);
						i--;
					}
				}
			}
		}
		
		public function checkItem(p1:Player){
			if(p1.CardUsing.Effect == "ner"){
				p1.Mana += p1.CardUsing.Modifier;
			}
			else if(p1.CardUsing.Effect == "nerG"){
				p1.Mana += p1.CardUsing.Modifier;
				attackAgain = true;
			}
			else if(p1.CardUsing.Effect == "atG"){
				p1.Modifiers.push(new Modifier("attack", p1.CardUsing.Modifier, 1));
			}
			else if(p1.CardUsing.Effect == "adG"){
				p1.Modifiers.push(new Modifier("attack", p1.CardUsing.Modifier, 1));
				
				// if they are in the defense phase, it affects them currently.  Otherwise
				if(!p1.IsAttacking)
					p1.TempDefense = p1.CardUsing.Modifier;
				else
					p1.Modifiers.push(new Modifier("defense", p1.CardUsing.Modifier, 1));
			}
			else if(p1.CardUsing.Effect == "atkP"){ // "poison" effect that lasts for three turns
				p1.Modifiers.push(new Modifier("hp", p1.CardUsing.Modifier, 3));
			}
			else if(p1.CardUsing.Effect == "defP"){
				p1.Modifiers.push(new Modifier("defense", p1.CardUsing.Modifier, 2));
			}
			else if(p1.CardUsing.Effect == "hp"){
				p1.Hp += p1.CardUsing.Modifier;
			}
			else if(p1.CardUsing.Effect == "pwr"){
				p1.PoweredUp = true;
				p1.Modifiers.push(new Modifier("power", 0, 2));
			}
		}
		
				
		// checks if hit
		public function checkIfHit(p1:Player):Boolean{
			var randomAmount = Math.random();
			var hit:Boolean;
			if(randomAmount > p1.Accuracy - p1.CardUsing.Accuracy - accModifier){
				hit = true;
			}
			else{
				hit = false;
			}
			return hit;
		}
		
		// checks to see which player pressed the keys
		public function pressed(e:KeyboarderEvent){
			if(animationDone){
				if(!player1.MoveComplete && (e.keyCode == 65 || e.keyCode == 68 || e.keyCode == 87 || e.keyCode == 83 || e.keyCode == 69 || e.keyCode == 81 || e.keyCode == 82 || e.keyCode == 70)){
					player1.Gui.selectCard(e.keyCode);
				}
				else if(!player2.MoveComplete && (e.keyCode == 85 || e.keyCode == 73 || e.keyCode == 79 || e.keyCode == 80 || e.keyCode == 74 || e.keyCode == 76 || e.keyCode == 75 || e.keyCode == 186)){
					player2.Gui.selectCard(e.keyCode);
				}
			}
		}
		
		// checks to see if the game has ended
		public function checkLose():Boolean{
			if(player1.Hp <= 0 || player2.Hp <= 0){
				// game over
				trace("Game Over");
				gb.gotoAndStop("win");
				channel2.stop();
				channel2.removeEventListener(Event.SOUND_COMPLETE, loopMusic);
				return true;
			}
			return false;
		}
		
		public function destroy(){
			removeEventListener(Event.ENTER_FRAME, update);
			removeEventListener(Event.ENTER_FRAME, drawGame);
		}
		
		
	}
	
}
